package org.jsola.hr.service.impl;

import org.jsola.core.Page;
import org.jsola.hr.common.ExampleKit;
import org.jsola.hr.common.HrLogKit;
import org.jsola.hr.constant.HrConstants;
import org.jsola.hr.dao.IAttendCalendarDAO;
import org.jsola.hr.dto.AttendCalendarAddDTO;
import org.jsola.hr.dto.AttendCalendarUpdateDTO;
import org.jsola.hr.entity.AttendCalendarDO;
import org.jsola.hr.query.AttendCalendarQuery;
import org.jsola.hr.service.IAttendCalendarService;
import org.jsola.hr.vo.AttendCalendarListVO;
import org.jsola.hr.vo.AttendCalendarVO;
import org.jsola.hr.vo.AttendNeedPunchVO;
import org.jsola.user.core.TokenUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author zhr
 */
@Service("hrAttendCalendarServiceImpl")
public class AttendCalendarServiceImpl implements IAttendCalendarService {

    @Autowired
    private IAttendCalendarDAO attendCalendarDAO;

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public AttendCalendarVO save(AttendCalendarAddDTO attendCalendarAddDTO, TokenUser tokenUser) {
        // 转DO
        AttendCalendarDO attendCalendarDO = attendCalendarAddDTO.to(AttendCalendarDO.class);
        // 保存
        attendCalendarDO = save(attendCalendarDO, tokenUser.getSiteId(), tokenUser.getUserId());
        HrLogKit.logForSave("新增考勤日历", "saveAttendCalendar", attendCalendarDO.getId(), tokenUser);
        return attendCalendarDO.to(AttendCalendarVO.class);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int update(AttendCalendarUpdateDTO attendCalendarUpdateDTO, TokenUser tokenUser) {
        //转DO
        AttendCalendarDO attendCalendarDO = attendCalendarUpdateDTO.to(AttendCalendarDO.class);
        HrLogKit.logForUpdate("修改考勤日历", "updateAttendCalendar", attendCalendarDO.getId(), tokenUser);
        //根据主键更新，只更新非null值
        return updateByIdSelective(attendCalendarDO, tokenUser.getSiteId(), tokenUser.getUserId());
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int deleteByIds(TokenUser tokenUser, String... attendCalendarIds) {
        HrLogKit.logForDelete("批量删除考勤日历", "deleteAttendCalendarByIds"
                , Arrays.toString(attendCalendarIds), tokenUser);
        return logicalDeleteByIds(tokenUser.getSiteId(), tokenUser.getUserId(), (Object[]) attendCalendarIds);
    }


    @Override
    public AttendCalendarVO selectById(String attendCalendarId, String siteId) {
        AttendCalendarDO attendCalendarDO = selectDOById(attendCalendarId, siteId);
        if (attendCalendarDO == null) {
            return null;
        }
        return attendCalendarDO.to(AttendCalendarVO.class);
    }

    @Override
    public List<AttendCalendarListVO> select(AttendCalendarQuery attendCalendarQuery, String siteId) {
        List<AttendCalendarDO> attendCalendarDOList = selectDO(attendCalendarQuery, siteId);
        if (CollectionUtils.isEmpty(attendCalendarDOList)) {
            return attendCalendarDOList == null ? null : new ArrayList<>();
        }
        return attendCalendarDOList.stream()
                .map(attendCalendarDO -> attendCalendarDO.to(AttendCalendarListVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public int selectCount(AttendCalendarQuery attendCalendarQuery, String siteId) {
        Example example = buildExample(attendCalendarQuery, siteId);
        return attendCalendarDAO.selectCountByExample(example);
    }

    @Override
    public Page<AttendCalendarListVO> selectPage(AttendCalendarQuery attendCalendarQuery, String siteId) {
        Example example = buildExample(attendCalendarQuery, siteId);
        Page<AttendCalendarDO> page = attendCalendarDAO.selectPageByExample(example,
                attendCalendarQuery.getPageNo(),
                attendCalendarQuery.getPageSize());

        return page.to(AttendCalendarListVO.class);
    }

    @Override
    public AttendCalendarDO selectDOById(String attendCalendarId, String siteId) {
        return listById(attendCalendarId, siteId);
    }

    @Override
    public List<AttendCalendarDO> selectDO(AttendCalendarQuery attendCalendarQuery, String siteId) {
        Example example = buildExample(attendCalendarQuery, siteId);
        return attendCalendarDAO.selectByExample(example);
    }

    @Override
    public int deleteByAttendPlanId(String attendPlanId, String siteId) {
        AttendCalendarQuery attendCalendarQuery = new AttendCalendarQuery();
        attendCalendarQuery.setAttendPlanId(attendPlanId);
        Example example = buildExample(attendCalendarQuery, siteId);
        return attendCalendarDAO.deleteByExample(example);
    }

    @Override
    public AttendNeedPunchVO isNeedPunchOfDaily(String attendPlanId, String attendDateStr, String siteId) {

        AttendNeedPunchVO attendNeedPunchVO = new AttendNeedPunchVO();
        boolean isSpecialDate = false;
        boolean isNeedPunchOfDaily = false;

        // 年
        String yearly = attendDateStr.split("-")[0];
        // 月
        String monthly = attendDateStr.split("-")[1];
        // 日
        String daily = attendDateStr.split("-")[2];

        AttendCalendarQuery attendCalendarQuery = new AttendCalendarQuery();
        attendCalendarQuery.setAttendPlanId(attendPlanId);
        attendCalendarQuery.setYear(yearly);
        attendCalendarQuery.setMonth(monthly);
        attendCalendarQuery.setDay(daily);
        List<AttendCalendarDO> attendCalendarDOList = this.selectDO(attendCalendarQuery, siteId);

        if (attendCalendarDOList.size() <= 0) {
            attendNeedPunchVO.setIsSpecialDate(isSpecialDate);
            attendNeedPunchVO.setIsNeedPunchOfDaily(isNeedPunchOfDaily);
            return attendNeedPunchVO;
        }

        isSpecialDate = true;

        // 是否考勤 : 1-是,0-否
        AttendCalendarDO attendCalendarDO = attendCalendarDOList.get(0);
        if (attendCalendarDO.getNeedAttend()) {
            isNeedPunchOfDaily = true;
            attendNeedPunchVO.setAttendPeriodJson(attendCalendarDO.getAttendPeriodJson());
        } else {
            isNeedPunchOfDaily = false;
        }

        attendNeedPunchVO.setIsSpecialDate(isSpecialDate);
        attendNeedPunchVO.setIsNeedPunchOfDaily(isNeedPunchOfDaily);

        return attendNeedPunchVO;
    }

    @Override
    public int logicDelByAttendPlanId(String attendPlanId, TokenUser tokenUser) {

        // 查询
        AttendCalendarQuery attendCalendarQuery = new AttendCalendarQuery();
        attendCalendarQuery.setAttendPlanId(attendPlanId);
        List<AttendCalendarDO> dataList = this.selectDO(attendCalendarQuery, tokenUser.getSiteId());
        if (dataList.size() <= 0) {
            return 0;
        }

        for (AttendCalendarDO attendCalendar : dataList) {
            AttendCalendarDO attendCalendarDO = new AttendCalendarDO();
            attendCalendarDO.setId(attendCalendar.getId());
            attendCalendarDO.setValid(false);
            attendCalendarDO.setModifiedUserId(tokenUser.getUserId());
            attendCalendarDO.setGmtModified(new Date());

            attendCalendarDAO.updateByPrimaryKeySelective(attendCalendarDO);
        }

        return 0;
    }

    /**
     * 根据查询参数，构建example
     *
     * @param attendCalendarQuery 查询参数
     * @param siteId              所属站点id
     * @return example
     */
    private Example buildExample(AttendCalendarQuery attendCalendarQuery, String siteId) {
        Example example = new Example(AttendCalendarDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        if (attendCalendarQuery.getAttendPlanId() != null) {
            example.and().andLike("attendPlanId", "%" + attendCalendarQuery.getAttendPlanId() + "%");
        }
        if (attendCalendarQuery.getYear() != null) {
            example.and().andEqualTo("year", attendCalendarQuery.getYear());
        }
        if (attendCalendarQuery.getMonth() != null) {
            example.and().andEqualTo("month", attendCalendarQuery.getMonth());
        }
        if (attendCalendarQuery.getDay() != null) {
            example.and().andEqualTo("day", attendCalendarQuery.getDay());
        }
        if (attendCalendarQuery.getDateType() != null) {
            example.and().andEqualTo("dateType", attendCalendarQuery.getDateType());
        }
        if (attendCalendarQuery.getNeedAttend() != null) {
            example.and().andEqualTo("needAttend", attendCalendarQuery.getNeedAttend());
        }
        if (attendCalendarQuery.getAttendPeriodJson() != null) {
            example.and().andLike("attendPeriodJson", "%" + attendCalendarQuery.getAttendPeriodJson() + "%");
        }
        if (attendCalendarQuery.getReason() != null) {
            example.and().andLike("reason", "%" + attendCalendarQuery.getReason() + "%");
        }
        if (attendCalendarQuery.getCompanyId() != null) {
            example.and().andEqualTo("companyId", attendCalendarQuery.getCompanyId());
        }
        if (attendCalendarQuery.getGmtCreateStart() != null &&
                attendCalendarQuery.getGmtCreateEnd() != null) {
            example.and().andBetween("gmtCreate", attendCalendarQuery.getGmtCreateStart(),
                    attendCalendarQuery.getGmtCreateEnd());
        }
        if (attendCalendarQuery.getCreateUserId() != null) {
            example.and().andLike("createUserId", "%" + attendCalendarQuery.getCreateUserId() + "%");
        }
        if (attendCalendarQuery.getGmtModifiedStart() != null &&
                attendCalendarQuery.getGmtModifiedEnd() != null) {
            example.and().andBetween("gmtModified", attendCalendarQuery.getGmtModifiedStart(),
                    attendCalendarQuery.getGmtModifiedEnd());
        }
        if (attendCalendarQuery.getModifiedUserId() != null) {
            example.and().andLike("modifiedUserId", "%" + attendCalendarQuery.getModifiedUserId() + "%");
        }
        // 排序
        ExampleKit.setExampleOrder(example, attendCalendarQuery.getOrders());
        return example;
    }
}




